/*
*  Copyright 2019-2020 Zheng Jie
*
*  Licensed under the Apache License, Version 2.0 (the "License");
*  you may not use this file except in compliance with the License.
*  You may obtain a copy of the License at
*
*  http://www.apache.org/licenses/LICENSE-2.0
*
*  Unless required by applicable law or agreed to in writing, software
*  distributed under the License is distributed on an "AS IS" BASIS,
*  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*  See the License for the specific language governing permissions and
*  limitations under the License.
*/
package me.zhengjie.modules.gis.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import me.zhengjie.modules.gis.domain.FeedHistory;
import me.zhengjie.utils.*;
import lombok.RequiredArgsConstructor;
import me.zhengjie.modules.gis.repository.FeedHistoryRepository;
import me.zhengjie.modules.gis.service.FeedHistoryService;
import me.zhengjie.modules.gis.service.dto.FeedHistoryDto;
import me.zhengjie.modules.gis.service.dto.FeedHistoryQueryCriteria;
import me.zhengjie.modules.gis.service.mapstruct.FeedHistoryMapper;
import me.zhengjie.utils.map.LonlatConver;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.web.client.RestTemplate;

import java.math.BigDecimal;
import java.util.*;
import java.io.IOException;
import javax.servlet.http.HttpServletResponse;
import java.util.concurrent.ConcurrentHashMap;

/**
* @website https://el-admin.vip
* @description 服务实现
* @author ZhuangBing Yan
* @date 2022-08-15
**/
@Service
@RequiredArgsConstructor
@CacheConfig(cacheNames = "feedHistory")
public class FeedHistoryServiceImpl implements FeedHistoryService {

    private final FeedHistoryRepository feedHistoryRepository;
    private final FeedHistoryMapper feedHistoryMapper;

    private static Map<String,BigDecimal[]> AREA = new HashMap<>();
    static{
        AREA.put("虎丘区",new BigDecimal[]{new BigDecimal("120.566833"),new BigDecimal("31.294845")});
        AREA.put("姑苏区",new BigDecimal[]{new BigDecimal("120.617296"),new BigDecimal("31.336392")});
        AREA.put("吴中区",new BigDecimal[]{new BigDecimal("120.631898"),new BigDecimal("31.264212")});
        AREA.put("吴江区",new BigDecimal[]{new BigDecimal("120.645158"),new BigDecimal("31.138677")});
        AREA.put("相城区",new BigDecimal[]{new BigDecimal("120.566833"),new BigDecimal("31.294845")});
        AREA.put("工业园区",new BigDecimal[]{new BigDecimal("120.717093"),new BigDecimal("31.322206")});
        AREA.put("高新区",new BigDecimal[]{new BigDecimal("120.553530"),new BigDecimal("31.300147")});
    }



    @Override
    public Map<String,Object> queryAll(FeedHistoryQueryCriteria criteria, Pageable pageable){
        Page<FeedHistory> page = feedHistoryRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder),pageable);
        return PageUtil.toPage(page.map(feedHistoryMapper::toDto));
    }

    @Override
    public List<FeedHistoryDto> queryAll(FeedHistoryQueryCriteria criteria){
        return feedHistoryMapper.toDto(feedHistoryRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder)));
    }

    @Override
    @Transactional
    public FeedHistoryDto findById(Long id) {
        FeedHistory feedHistory = feedHistoryRepository.findById(id).orElseGet(FeedHistory::new);
        ValidationUtil.isNull(feedHistory.getId(),"FeedHistory","id",id);
        return feedHistoryMapper.toDto(feedHistory);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public FeedHistoryDto create(FeedHistory resources) {
        return feedHistoryMapper.toDto(feedHistoryRepository.save(resources));
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void update(FeedHistory resources) {
        FeedHistory feedHistory = feedHistoryRepository.findById(resources.getId()).orElseGet(FeedHistory::new);
        ValidationUtil.isNull( feedHistory.getId(),"FeedHistory","id",resources.getId());
        feedHistory.copy(resources);
        feedHistoryRepository.save(feedHistory);
    }

    @Override
    public void deleteAll(Long[] ids) {
        for (Long id : ids) {
            feedHistoryRepository.deleteById(id);
        }
    }

    @Override
    public void download(List<FeedHistoryDto> all, HttpServletResponse response) throws IOException {
        List<Map<String, Object>> list = new ArrayList<>();
        for (FeedHistoryDto feedHistory : all) {
            Map<String,Object> map = new LinkedHashMap<>();
            map.put("车牌号", feedHistory.getCarNumber());
            map.put("卡号", feedHistory.getCardNumber());
            map.put("货物名称", feedHistory.getGoodName());
            map.put("发货单位", feedHistory.getDeliverCompany());
            map.put("区域", feedHistory.getArea());
            map.put("运输单位", feedHistory.getFeedCompany());
            map.put("处置单位", feedHistory.getDisposeCompany());
            map.put("毛重（吨）", feedHistory.getGrossWeight());
            map.put("皮重(吨)", feedHistory.getTareWeight());
            map.put("扣减(吨)", feedHistory.getDeductionWeight());
            map.put("净重(吨)", feedHistory.getNetWeight());
            map.put("出单人(创建人)", feedHistory.getCreateBy());
            map.put("车间名称", feedHistory.getWorkShopName());
            map.put("数据类型()", feedHistory.getType());
            map.put("数据状态", feedHistory.getStatus());
            map.put("是否删除( 0 未删除  1 已删除)", feedHistory.getIsDel());
            map.put("创建时间", feedHistory.getCreateTime());
            map.put("修改人", feedHistory.getUpdateBy());
            map.put("修改时间", feedHistory.getUpdateTime());
            map.put("进厂时间", feedHistory.getEnterInTime());
            list.add(map);
        }
        FileUtil.downloadExcel(list, response);
    }

    @Override
    public Map<String, Object> getByDate(String enterInTime, Pageable pageable) {
        Page<FeedHistory> page = feedHistoryRepository.getByDateForPage(enterInTime, pageable);
        return PageUtil.toPage(page.map(feedHistoryMapper::toDto));
    }

    @Override
    public Map<String, Object> getLineDataByDate(String enterInTime, Pageable pageable) {
        Page<Map<String,Object>> page = feedHistoryRepository.getLineDataByDate(enterInTime, pageable);
        return PageUtil.toPage(page);
    }

    @Override
    @Transactional
    @Cacheable(key = "'startPoint:' + #enterInTime")
    public  List<ConcurrentHashMap<String,Object>> findStartPoint(String enterInTime) {
         List<Map<String,Object>> result = feedHistoryRepository.findStartPoint(enterInTime);

        List<ConcurrentHashMap<String,Object>> temp = new ArrayList<>();
       for(Map<String,Object> ele:result){
           Object netWeight = ele.get("netWeight");
           Object startLng = ele.get("startLng");
           Object startLat = ele.get("startLat");
           ConcurrentHashMap<String,Object> tel = new ConcurrentHashMap<>();
           double[] doubles = LonlatConver.gcj02_To_Wgs84(Double.parseDouble(startLng.toString()), Double.parseDouble(startLat.toString()));
           tel.put("point",new BigDecimal[]{new BigDecimal(doubles[0]+""),new BigDecimal(doubles[1]+"")});
           tel.put("size",new BigDecimal(netWeight.toString()));
           if(Math.random()*100 <20){
               tel.put("isIng",true);
           }else{
               tel.put("isIng",false);
           }
           temp.add(tel);
       }

        return temp;
    }

    @Override
    @Cacheable(key = "'Area:' + #enterInTime")
    public List<ConcurrentHashMap<String, Object>> findArea(String enterInTime) {
        List<Map<String,Object>> result = feedHistoryRepository.findArea(enterInTime);
        List<ConcurrentHashMap<String,Object>> temp = new ArrayList<>();
        for(Map<String,Object> ele:result){
            Object num = ele.get("num");
            Object weight = ele.get("weight");
            Object area = ele.get("area");
            ConcurrentHashMap<String,Object> tel = new ConcurrentHashMap<>();
            BigDecimal[] bigDecimals = AREA.get(StringUtils.isEmpty(area.toString())?"虎丘区":area);
            double[] par = LonlatConver.gcj02_To_Wgs84(bigDecimals[0].doubleValue(),bigDecimals[1].doubleValue() );
            tel.put("point",new BigDecimal[]{new BigDecimal(par[0]+""),new BigDecimal(par[1]+"")});
            tel.put("num",num);
            tel.put("weight",weight);
            temp.add(tel);
        }
        return temp;
    }

//    @Override
//    public Map<String, Object> getByDate(Timestamp enterInTime, Pageable pageable) {
//        Page<FeedHistory> page = feedHistoryRepository.findAll((root, criteriaQuery, criteriaBuilder) -> {
//            Predicate like = criteriaBuilder.like(root.get("userName").as(String.class), "asd");
//            criteriaQuery.where(like);
//            List<Predicate> predicates = new ArrayList<Predicate>();
//            predicates.add(cb.like(root.get("userName").as(String.class), "%"+webUser.getUserName() + "%"));
//            predicates.add(cb.like(root.get("email").as(String.class), "%"+webUser.getEmail() + "%"));
//            predicates.add(cb.like(root.get("phoneNo").as(String.class), "%"+webUser.getPhoneNo() + "%"));
//            predicates.add(cb.equal(root.get("isValid").as(String.class), webUser.getIsValid()));
//
////            SimpleDateFormat f = new SimpleDateFormat("yyyy-MM-dd");
////            try {
////                if (null != webUser.getCreateTimeStart() && !"".equals(webUser.getCreateTimeStart()))
////                    predicates.add(cb.greaterThanOrEqualTo(root.get("createTime").as(Date.class),
////                            f.parse(webUser.getCreateTimeStart())));
////                if (null != webUser.getCreateTimeEnd() && !"".equals(webUser.getCreateTimeEnd()))
////                    predicates.add(cb.lessThan(root.get("createTime").as(Date.class),
////                            new Date(f.parse(webUser.getCreateTimeEnd()).getTime() + 24 * 3600 * 1000)));
////            } catch (ParseException e) {
////                e.printStackTrace();
////            }
//            return query.where(predicates.toArray(new Predicate[predicates.size()])).getRestriction();
//
//        },pageable);
//        return PageUtil.toPage(page.map(feedHistoryMapper::toDto));
//    }
}